-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Fixes components to remount when passed from a parent object #3570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
…n prop (cherry picked from commit cdd40ed)
|
I tried this and confirmed that it fixes the example app from #3497 |
T4rk1n
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💃
|
The redraw test show one less redraw after a click that might be a regression. |
|
Yeah, I wasn't sure how this would perform with specifically that instance. |
|
Do you think some apps are relying on the current behavior of holding the state, and this might be considered a breaking change? |
Yes it might effect apps that relies on keeping state even if the content is updated but it's expected to be the same component (with same id), it would reset to what is given back, which might be the correct behavior since it's a new component from the callback. Kind of an undocumented behavior and it's not tested beside the redraw component. |
|
The fix doesn't work for this app (shared by DE client): Workaround is to pass id to the layout import dash
from dash import Input, Output, dcc, html
app = dash.Dash(__name__, prevent_initial_callbacks=True)
def layout_1():
return dcc.Tabs(
# id="tabs", # NOTE: adding id somehow fixes the issue, same for layout_2
value="tab1",
children=[
dcc.Tab(
html.H2("First step is to switch to the next tab"),
value="tab1",
label="Click on next tab =>",
),
dcc.Tab(
html.H2("Now click on 'Layout 2' or 'Layout 3' button"),
value="tab2",
label="Click on me!",
),
],
)
def layout_2():
return html.Div(
[
html.H2("Click anywhere inside the red rectangle to see the issue"),
html.Button("Button", style={"backgroundColor": "green", "padding": "50px"}),
html.P(
"Explenation: this Div inside container is replaced with dcc.Tabs after clicking"
),
]
)
def layout_3():
return dcc.Tabs(
value="tab1",
children=[
dcc.Tab(
html.H2("After clicking on this text last tab will disappear"),
value="tab1",
label="Tab 1",
),
# NOTE: commenting the below tabs and repeating the steps will get you an error
dcc.Tab("1", label="Tab 2"),
dcc.Tab("2", label="Tab 3"),
],
)
app.layout = html.Div(
[
html.H1("Dash bug showcase"),
html.Button("Layout 1", id="button-1"),
html.Button("Layout 2", id="button-2", style={"marginLeft": "10px"}),
html.Button("Layout 3", id="button-3", style={"marginLeft": "10px"}),
html.P(
layout_1(),
id="layout",
style={"padding": "20px", "border": "2px dashed red"},
),
]
)
@app.callback(
Output("layout", "children"),
Input("button-1", "n_clicks"),
Input("button-2", "n_clicks"),
Input("button-3", "n_clicks"),
)
def update_output(_1, _2, _3):
if dash.ctx.triggered_id == "button-1":
return layout_1()
if dash.ctx.triggered_id == "button-2":
return layout_2()
if dash.ctx.triggered_id == "button-3":
return layout_3()
if __name__ == "__main__":
app.run(debug=True) |
fixes #3330
fixes issue where components wouldnt remount when passed as a children prop
eg:
Running this in the current dash will result in the component keeping some state even though it should technically be unmounted and remounted.